﻿#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
// 原题连接：https://leetcode.cn/problems/two-sum-ii-input-array-is-sorted/
/*
题目描述：
给你一个下标从 1 开始的整数数组 numbers ，该数组已按 非递减顺序排列  ，
请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设这两个数分别是 numbers[index1] 和 numbers[index2] ，
则 1 <= index1 < index2 <= numbers.length 。
以长度为 2 的整数数组 [index1, index2] 的形式返回这两个整数的下标 index1 和 index2。
你可以假设每个输入 只对应唯一的答案 ，而且你 不可以 重复使用相同的元素。
你所设计的解决方案必须只使用常量级的额外空间。

示例 1：
输入：numbers = [2,7,11,15], target = 9
输出：[1,2]
解释：2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。

示例 2：
输入：numbers = [2,3,4], target = 6
输出：[1,3]
解释：2 与 4 之和等于目标数 6 。因此 index1 = 1, index2 = 3 。返回 [1, 3] 。

示例 3：
输入：numbers = [-1,0], target = -1
输出：[1,2]
解释：-1 与 0 之和等于目标数 -1 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。
 

提示：
2 <= numbers.length <= 3 * 104
-1000 <= numbers[i] <= 1000
numbers 按 非递减顺序 排列
-1000 <= target <= 1000
仅存在一个有效答案
*/
// 方法——双指针
/*
思路：
起始时我们让一个指针left指向数组的第一个元素，让一个指针right指向数组的最后一个元素，
我们可以利用数组的有序性让numbers[left] + numbers[right]往target逼近
当numbers[left] + numbers[right] < target时，让left++，以增大和的值
当numbers[left] + numbers[right] > target时，让right--，以减小和的值
当numbers[left] + numbers[right]时， 返回left+1和right+1两个坐标即可。
*/

// 有了以上思路，那我们写起代码来也就水到渠成了：
int* twoSum(int* numbers, int numbersSize, int target, int* returnSize) {
    assert(numbers && returnSize);
    *returnSize = 2;
    int* answer = (int*)malloc(2 * sizeof(int));
    if (NULL == answer) {
        perror("malloc fail");
        return NULL;
    }
    answer[0] = -1;
    answer[1] = -1;
    int left = 0;
    int right = numbersSize - 1;
    while (left < right) {
        if (numbers[left] + numbers[right] < target) {
            left++;
        }
        else if (numbers[left] + numbers[right] > target) {
            right--;
        }
        else {
            answer[0] = left + 1;
            answer[1] = right + 1;
            break;
        }
    }
    return answer;
}
// 时间复杂度：O(n)，n为数组长度，最坏情况下，我们只需要遍历一遍数组及可。
// 空间复杂度：O(1)，我们只需要用到常数级的额外空间。

int main() {
    int nums[] = { 2,7,11,15 };
    int numsSize = sizeof(nums) / sizeof(nums[0]);
    int target = 9;
    int return_size = 0;
    int *returnSize = &return_size;
    int *result = twoSum(nums, numsSize, target, returnSize);
    printf("[%d, %d]\n", result[0], result[1]);
    return 0;
}